class IUP_COLOR_BAR
-- Creates a color palette to enable a color selection from several samples.
-- It can select one or two colors. The primary color is selected with the
-- left mouse button, and the secondary color is selected with the right mouse
-- button. You can double click a cell to change its color and you can double
-- click the preview area to switch between primary and secondary colors.
--
-- This is an additional control that depends on the CD library.
--
-- It inherits from IUP_CANVAS.
--
-- NOTES
--
-- When the control has the focus the keyboard can be used to change the 
-- colors and activate the callbacks. Use the arrow keys to move from cell to
-- cell, Home goes to the first cell, End goes to the last cell. Space will
-- activate the SELECT callback for the primary color, Ctrl+Space will 
-- activate the SELECT callback for the secondary color. Shift+Space will
-- activate the EXTENTED callback. Shift+Enter will activate the CELL callback.

inherit
	IUP_CONTROLS
		redefine
			set_size,
			execute_cell,
			execute_extended,
			execute_select,
			execute_switch
		end

create {ANY}
	color_bar

feature {ANY}

	color_bar
		local
			a_color_bar: POINTER
		do
			a_color_bar := int_color_bar
			set_widget(a_color_bar)
		end

	-- Attributes

	set_bufferize (state: BOOLEAN)
		-- (non inheritable): Disables the automatic redrawing of the control,
		-- so many attributes can be changed without many redraws.
		-- Default: "False". When set to "False" the control is redrawn.
		do
			iup_open.set_attribute(Current, "BUFFERIZE", boolean_to_yesno(state))
		end

	set_cell_n_color (n, red, green, blue: INTEGER)
		-- Set the color of the "n" cell. "n" can be from 0 to number of
		-- cells - 1.
		do
			iup_open.set_attribute_id(Current, "CELL", n, rgb_to_string(red, green, blue))
		end

	get_cell_n_color (n: INTEGER): TUPLE[INTEGER, INTEGER, INTEGER]
		-- Get the color of the "n" cell. "n" can be from 0 to number of
		-- cells - 1.
		local
			cl: STRING
		do
			cl := iup_open.get_attribute_id(Current, "CELL", n)

			Result := string_to_rgb(cl)
		end

	set_number_of_cells (n: INTEGER)
		-- (non inheritable): Contains the number of color cells. Default: "16".
		-- The maximum number of colors is 256. The default colors use the
		-- same set of IUP_IMAGE.
		require
			n > 0
		do
			iup_open.set_attribute(Current, "NUM_CELLS", n.to_string)
		end

	get_count: INTEGER
		-- Returns the number of color cells.
		do
			Result := iup_open.get_int(Current, "COUNT")
		end

	set_number_of_parts (num: INTEGER)
		-- (non inheritable): Set the number of lines or columns. Default: "1".
		require
			num > 0
		do
			iup_open.set_attribute(Current, "NUM_PARTS", num.to_string)
		end

	get_number_of_parts: INTEGER
		-- Returns the number of lines or columns.
		do
			Result := iup_open.get_int(Current, "NUM_PARTS")
		end

	set_horizontal_orientation
		do
			iup_open.set_attribute(Current, "ORIENTATION", "HORIZONTAL")
		end

	set_vertical_orientation
		-- This is the default value.
		do
			iup_open.set_attribute(Current, "ORIENTATION", "VERTICAL")
		end

	is_horizontal: BOOLEAN
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "ORIENTATION")

			if str.is_equal("HORIZONTAL") then
				Result := True
			else
				Result := False
			end
		end

	is_vertical: BOOLEAN
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "ORIENTATION")

			if str.is_equal("VERTICAL") then
				Result := True
			else
				Result := False
			end
		end

	set_preview_size (width, height: INTEGER)
		-- (non inheritable): Fixes the size of the preview area in pixels.
		-- The default size is dynamically calculated from the size of the
		-- control. The size is reset to the default when "set_show_preview"
		-- is set to False.
		require
			width > 0
			height > 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)
			
			iup_open.set_attribute(Current, "PREVIEW_SIZE", size)
		end

	set_show_preview (state: BOOLEAN)
		-- Controls the display of the preview area. Default: "True". 
		do
			iup_open.set_attribute(Current, "SHOW_PREVIEW", boolean_to_yesno(state))
		end

	set_show_secondary (state: BOOLEAN)
		-- Controls the existence of a secondary color selection.
		-- Default: "False". 
		do
			iup_open.set_attribute(Current, "SHOW_SECONDARY", boolean_to_yesno(state))
		end

	set_size (width, height: INTEGER)
		-- Specifies the element User size, and returns the Current size, in 
		-- units proportional to the size of a character.
		-- You must define "size" or "raster size".
		do
			Precursor (width, height)
		end

	set_primary_cell (index: INTEGER)
		-- (non inheritable): Set the index of the primary color.
		-- Default "0" (black).
		require
			index >= 0
		do
			iup_open.set_attribute(Current, "PRIMARY_CELL", index.to_string)
		end

	get_primary_cell: INTEGER
		-- Return the index of the primary color.
		do
			Result := iup_open.get_int(Current, "PRIMARY_CELL")
		end

	set_seconday_cell (index: INTEGER)
		-- (non inheritable): Set the index of the secondary color.
		-- Default "15" (white).
		require
			index >= 0
		do
			iup_open.set_attribute(Current, "SECONDARY_CELL", index.to_string)
		end

	get_secondary_cell: INTEGER
		-- Return the index of the secondary color.
		do
			Result := iup_open.get_int(Current, "SECONDARY_CELL")
		end

	set_squared (state: BOOLEAN)
		-- Controls the aspect ratio of the color cells. Non square cells
		-- expand equally to occupy all of the control area. Default: "True". 
		do
			iup_open.set_attribute(Current, "SQUARED", boolean_to_yesno(state))
		end

	set_shadowed (state: BOOLEAN)
		-- Controls the 3D effect of the color cells. Default: "True". 
		do
			iup_open.set_attribute(Current, "SHADOWED", boolean_to_yesno(state))
		end

	set_transparency (red, green, blue: INTEGER)
		-- Contains a color that will be not rendered in the color palette.
		-- The color cell will have a white and gray chess pattern. It can
		-- be used to create a palette with less colors than the number of cells.
		do
			iup_open.set_attribute(Current, "TRANSPARENCY", rgb_to_string(red, green, blue))
		end

	-- Callbacks

	set_cb_cell (act: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER], TUPLE[INTEGER, INTEGER, INTEGER]])
		-- Called when the user double clicks a color cell to change its value.
		--
		-- ih: identifier of the element that activated the event.
		-- cell: index of the selected cell. If the user double click a preview
		-- cell, the respective index is returned.
		--
		-- Returns: a tuple with new color (r, g, b) integers, or void to ignore 
		-- the change. By default nothing is changed.
		local
			operation: INTEGER
		do
			cb_cell := act

			if cb_cell /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "CELL_CB", "NONEEDED", operation)
		end

	set_cb_extended (act: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER], STRING])
		-- Called when the user right click a cell with the Shift key pressed.
		-- It is independent of the "set_show_secondary" attribute.
		local
			operation: INTEGER
		do
			cb_extended := act

			if cb_extended /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "EXTENDED_CB", "NONEEDED", operation)
		end

	set_cb_select (act: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER, INTEGER], STRING])
		-- Called when a color is selected. The primary color is selected with
		-- the left mouse button, and if existent the secondary is selected
		-- with the right mouse button.
		--
		-- ih: identifier of the element that activated the event.
		-- cell: index of the selected cell.
		-- type: indicates if the user selected a primary or secondary color.
		--       In can be: primary (1) or secondary (2).
		--
		-- Returns: If "IUP_IGNORE" the selection is not accepted. By default
		-- the selection is always accepted.
		local
			operation: INTEGER
		do
			cb_select := act

			if cb_select /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "SELECT_CB", "NONEEDED", operation)
		end

	set_cb_switch (act: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER, INTEGER], STRING])
		-- Called when the user double clicks the preview area outside the
		-- preview cells to switch the primary and secondary selections.
		-- It is only called if "set_show_secondary" is True.
		--
		-- ih: identifier of the element that activated the event.
		-- prim_cell: index of the actual primary cell.
		-- sec_cell: index of the actual secondary cell.
		--
		-- Returns: If "IUP_IGNORE" the switch is not accepted. By default
		-- the switch is always accepted.
		local
			operation: INTEGER
		do
			cb_switch := act

			if cb_switch /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "SWITCH_CB", "NONEEDED", operation)
		end

feature {IUP}

	execute_cell (cell: INTEGER): TUPLE[INTEGER, INTEGER, INTEGER]
		do
			Result := cb_cell.item([Current, cell])
		end

	execute_extended (cell: INTEGER): STRING
		do
			Result := cb_extended.item([Current, cell])
		end

	execute_select (cell, type: INTEGER): STRING
		local
			i: INTEGER
		do
			i := -1*type
						
			Result := cb_select.item([Current, cell, i])
		end

	execute_switch (prim_cell, sec_cell: INTEGER): STRING
		do
			Result := cb_switch.item([Current, prim_cell, sec_cell])
		end

feature {}

	cb_cell: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER], TUPLE[INTEGER, INTEGER, INTEGER]]
	cb_extended: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER], STRING]	
	cb_select: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER, INTEGER], STRING]
	cb_switch: FUNCTION[TUPLE[IUP_COLOR_BAR, INTEGER, INTEGER], STRING]

	-- Internal

	int_color_bar: POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupColorbar()"
         }"
      end
end

-- The MIT License (MIT)

-- Copyright (c) 2016, 2019 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
